home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / a86b.arc / COND.DOC < prev    next >
Encoding:
Text File  |  1986-06-23  |  8.5 KB  |  212 lines

  1. ---COND.DOC---
  2.  
  3. Conditional Assembly
  4. ----------- --------
  5.  
  6. This assembler has a conditional assembly feature, that allows you to specify
  7. that blocks of source code will or will not be assembled, according to the
  8. values of equated user symbols.  The controlling symbols can be declared in
  9. the program (and can thus be the result of assembly-time expressions), or they
  10. can be declared in the assembler invocation.
  11.  
  12. You should keep in mind the difference between conditional assembly, invoked
  13. by #IF, and the structured-programming feature, invoked by IF without the
  14. pound-sign.  #IF tests a condition at assembly-time, and can cause code to
  15. not be assembled and thus not appear in the program.  IF causes code to be
  16. assembled that tests a condition at run-time, possibly jumping over code.
  17. The skipped code will always appear in the program.
  18.  
  19. All conditional assembly lines are identified by a pound-sign # as the first
  20. non-blank character of a line.  The pound-sign is followed by one of the four
  21. keywords IF, ELSEIF, ELSE or ENDIF.
  22.  
  23. #IF starts a conditional-assembly block.  On the same line, following the #IF,
  24. you provide a name.  If the name is undefined, or if it has been equated to
  25. zero, then the following lines of code are skipped, up to the next matching
  26. #ELSEIF, #ELSE, or #ENDIF.  If the name is non-zero, then the following lines
  27. of code are assembled normally.  If a subsequent matching #ELSEIF or #ELSE is
  28. encountered, then code is skipped up to the matching #ENDIF.
  29.  
  30. #ELSEIF provides a multiple-choice facility for #IF-blocks.  You can give any
  31. number of #ELSEIFs between an #IF and its matching #ENDIF.  Each #ELSEIF has a
  32. name following it on the same line.  If the name following the #IF has zero
  33. value, then the assembler looks for the first non-zero name following an
  34. #ELSEIF, and assembles that block of code.  If there are no non-zero #ELSEIFs,
  35. then the #ELSE-block (if there is one) is assembled.
  36.  
  37. It is legal to provide an undefined name after #IF or #ELSEIF.  The name is
  38. interpreted as being false (zero), with no error.
  39.  
  40. You may precede the name in an #IF or #ELSEIF line with an exclamation point
  41. "!", which acts as a NOT-operator: code will be skipped if the name is non-zero
  42. instead of zero.
  43.  
  44. #ELSE marks the beginning of code to be assembled if all the previous blocks
  45. of an #IF have been skipped over.  There is no operand after the #ELSE.  There
  46. can be at most one #ELSE in an #IF-block, and it must appear after any #ELSEIFs.
  47.  
  48. #ENDIF marks the end of an #IF-block.  There is no operand after #ENDIF.
  49.  
  50. It is legal to have nested #IF-blocks; that is, #IF-blocks that are contained
  51. within other #IF-blocks.  #ELSEIF, #ELSE, and #ENDIF always refer to the
  52. innermost nested #IF-block.
  53.  
  54. As an example of conditional assembly, suppose that you have a program that
  55. comes in three versions: one for Texas, one for Oklahoma, and one for the
  56. rest of the nation.  The three programs differ in a limited number of places.
  57. Instead of keeping three different versions of the source code, you can keep
  58. one version, and use conditional assembly on the boolean varibales TEXAS and
  59. OKLAHOMA to control the assembler output.  A sample block would be:
  60.  
  61. #if TEXAS
  62.   DB 0,1,2,3
  63. #elseif OKLAHOMA
  64.   DB 4,5,6,7
  65. #else
  66.   DB 8,9,10,11
  67. #endif
  68.  
  69. If a block of code is to be assembled only if TEXAS is false, then you would
  70. use the exclamation-point operator:
  71.  
  72. #if !TEXAS
  73.   DB 0FF
  74. #endif
  75.  
  76.  
  77. Conditional Assembly and Macros
  78.  
  79. You may have conditional-assembly blocks either in macro-definitions or
  80. in macro expansions.  The only limitation is that if you have an #IF-block
  81. in a macro expansion, the entire block (i.e., the matching #ENDIF) must
  82. appear in the same macro expansion.  You cannot, for example, define a
  83. macro that is a synonym for #IF.
  84.  
  85. To have your conditional-assembly block apply to the macro defintion, you
  86. provide the block normally within the defintion.  For example:
  87.  
  88. X1 EQU 0
  89.   BAZ MACRO
  90. #if X1
  91.   DB 010
  92. #else
  93.   DB 011
  94. #endif
  95. #EM
  96.   BAZ
  97. X1 EQU 1
  98.   BAZ
  99.  
  100. In the above sequence of code, the conditional-assembly block is acted upon
  101. when the macro BAZ is defined.  The macro therefore consists of the single
  102. line DB 011, with all the conditional-assembly lines removed from the
  103. definition.  Thus, both expansions of BAZ produce the object-code byte of
  104. 011, even though the local label X1 has turned non-zero for the second
  105. invocation.
  106.  
  107. To have your conditional-assembly block appear in the macro expansion, you
  108. must literalize the pound-sign on each conditional-assembly line by giving
  109. two pound-signs:
  110.  
  111. X1 EQU 0
  112.   BAZ MACRO
  113. ##if X1
  114.   DB 010
  115. ##else
  116.   DB 011
  117. ##endif
  118. #EM
  119.   BAZ
  120. X1 EQU 1
  121.   BAZ
  122.  
  123. Now the entire conditional-assembly block is stored in the macro defintion, and
  124. acted upon each time the macro is expanded.  Thus, the two invocations of BAZ
  125. will produce the different object bytes 011 and 010, since X1 has become
  126. non-zero for the second expansion.
  127.  
  128. You will usually want your conditional-assembly blocks to be acted upon at
  129. macro-definition time, to save symbol-table space.  You will thus use the first
  130. form, with the single pound-signs.
  131.  
  132.  
  133. Conditional Assembly and the XREF Program
  134.  
  135. In most cases, the XREF program will recognize conditional-assembly blocks, and
  136. ignore skipped-code in its XREF compilation.  The last macro example above,
  137. however, is an example in which XREF will not skip the same blocks that the
  138. assembler will; because it falls under the following
  139.  
  140. WARNING: The XREF program will use the value of all symbols as it existed at
  141.    the end of assembly.  XREF does not parse statements that change the value of
  142.    local variables!  Thus, if you have conditional assembly based on a variable
  143.    whose value changes during assembly, XREF will compile different source than
  144.    the assembler assembled.
  145.  
  146. The above warning does not apply to invocation-variables, described below. If
  147. you wish to change the value of a conditional-control variable during assembly,
  148. and if you wish XREF to give accurate results, you should change the variable
  149. between file-names in the invocation, as described below.
  150.  
  151.  
  152. Declaring Variables in the Assembler Invocation
  153.  
  154. To facilitate the effective use of conditional assembly, this assembler allows
  155. you to declare boolean (true-false) symbols in the command-line that invokes
  156. the assembler.  The declarations can appear anywhere in the list of source file
  157. names.  They are distinguished from the file names by a leading equals-sign =.
  158. To declare a symbol TRUE (value = 1), give the name after the equals-sign.  DO
  159. NOT put any spaces between the equals-sign and the name! To declare a symbol
  160. FALSE (value = 0), you can give an equals-sign, an exclamation-point, then the
  161. name.  Again, DO NOT embed any blanks!  Example: if your source files are
  162. src1.8, src2.8, and src3.8, then you can assemble with TEXAS true by invoking
  163. the assembler as follows:
  164.  
  165.    a86 =TEXAS src1.8 src2.8 src3.8
  166.  
  167. You can assemble with TEXAS explicitly set to FALSE as follows:
  168.  
  169.    a86 =!TEXAS src1.8 src2.8 src3.8
  170.  
  171. Note that if TEXAS is used only as a conditional-assembly control, then you
  172. do not need to include the =!TEXAS in the invocation, because an undefined
  173. TEXAS will automatically be interpreted as false.
  174.  
  175.  
  176. Null Invocation Variable Names
  177.  
  178. The assembler will ignore an equals-sign by itself in the invocation line,
  179. without error.  This allows you to generate assembler-invocation lines using
  180. parameters that could be either boolean-variable-names, or null strings. For
  181. example, in the previously-mentioned TEXAS-OKLAHOMA-nation example, the program
  182. could be invoked via a .BAT file called "AMAKE.BAT", coded as follows:
  183.  
  184.       A86 =%1 *.8
  185.  
  186. You invoke the assembler by typing one of the following:
  187.  
  188.       amake texas
  189.       amake oklahoma
  190.       amake
  191.  
  192. The third line will produce the assembler-invocation  A86 = *.8; causing no
  193. invocation-variables to be declared.  Thus both TEXAS and OKLAHOMA will be
  194. false, which is exactly what you want for the rest-of-the-nation version of
  195. the program.
  196.  
  197.  
  198. Changing Values of Invocation Variables
  199.  
  200. The usual prohibition against changing the value of a symbol that is not a
  201. local-label does not apply to invocation-variables.  For example, suppose you
  202. have a conditional-control variable DEBUG, which will generate diagnostic code
  203. for debugging when it is true.  Suppose further that you have already debugged
  204. source files src1.8 and src3.8; but you are still working on src2.8. You may
  205. invoke the assembler as follows:
  206.  
  207.    a86 src1.8 =DEBUG src2.8 =!DEBUG src3.8
  208.  
  209. The variable DEBUG will be TRUE only during assembly of src2.8, just as you
  210. want.
  211.  
  212.